package com.request.service.impl.shop.yicheng;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.request.common.constants.RedisConstant;
import com.request.common.enums.RechargeTypeEnum;
import com.request.common.enums.SignTypeEnum;
import com.request.common.enums.YiChengErrorCodeEnum;
import com.request.common.enums.YiChengOrderStatusEnum;
import com.request.common.utils.HttpUtils;
import com.request.common.utils.SignUtils;
import com.request.entity.PhoneOrderWaitCheck;
import com.request.service.QueryOrderProcessor;
import com.request.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * Description:
 * Create DateTime: 2020-04-22 17:25
 *
 * 

 */
@Slf4j
@Service
public class YiChengQueryOrderProcessor implements QueryOrderProcessor {

    private static Map<String, String> HEADER_MAP = new HashMap<>(2);

    static {
        HEADER_MAP.put("Accept", "application/json;charset=utf-8");
    }

    @Resource
    private RedisService redisService;
    @Resource
    private ThreadPoolExecutor handlerOrderExecutor;

    @Override
    public void sendRequest(PhoneOrderWaitCheck orderWaitCheck) {
        handlerOrderExecutor.execute(() -> executeWaitOrderQuery(orderWaitCheck));
    }

    /**
     * 执行待查询订单查询
     *
     * @param phoneOrderWaitCheck 待查询订单
     */
    private void executeWaitOrderQuery(PhoneOrderWaitCheck phoneOrderWaitCheck) {
        Map<String, Object> params = new HashMap<>();
        String result = null;
        try {
            if (phoneOrderWaitCheck == null) {
                return;
            }

            params.put("userId", phoneOrderWaitCheck.getAppId());
            params.put("serialno", phoneOrderWaitCheck.getPlatformOrderNo());

            TreeMap<String, String> signMap = new TreeMap<>();
            signMap.put("a", phoneOrderWaitCheck.getPlatformOrderNo());
            signMap.put("b", phoneOrderWaitCheck.getAppId());
            signMap.put("c", phoneOrderWaitCheck.getAppKey());

            String sign = SignUtils.generateSignature(signMap, SignTypeEnum.MD5);

            params.put("sign", sign);

            result = sendRequestForWaitOrder(phoneOrderWaitCheck.getQuerySite(), params);

            JSONObject jsonObject = JSONObject.parseObject(result);
            String code = jsonObject.getString("code");

            if (!YiChengErrorCodeEnum.SUCCESS.getCode().equals(code)) {
                String desc = jsonObject.getString("desc");
                throw new RuntimeException("超时检查订单商户响应失败，状态码为" + code + ", 对应的信息为：" + desc);
            } else {
                JSONObject data = jsonObject.getJSONObject("data");

                String status = data.getString("status");
                String shopOrderNo = data.getString("id");
                String orderSn = data.getString("outOrderNo");
                String message = data.getString("statusDesc");
                phoneOrderWaitCheck.setShopOrderNo(shopOrderNo);
                phoneOrderWaitCheck.setOrderSn(orderSn);
                phoneOrderWaitCheck.setMessage(message);

                YiChengOrderStatusEnum statusEnum = YiChengOrderStatusEnum.getByCode(status);

                switch (statusEnum) {
                    case SUCCESS:
                        phoneOrderWaitCheck.setStatus(1);
                        saveWaitOrderQueryForSuccess(phoneOrderWaitCheck);
                        break;
                    case FAILED:
                        phoneOrderWaitCheck.setStatus(0);
                        saveWaitOrderQueryForSuccess(phoneOrderWaitCheck);
                        break;
                    case PROCESSING_0:
                    case PROCESSING_1:
                    case PROCESSING_2:
                    case NOT_CONFIRM:
                        saveWaitOrderQueryForProcessing(phoneOrderWaitCheck);
                        break;
                    default:
                        saveWaitOrderQueryForProcessing(phoneOrderWaitCheck);
                        break;
                }
            }
        } catch (Exception e) {
            saveWaitOrderQueryForProcessing(phoneOrderWaitCheck);
            log.error("【翼程】【超时检查】请求商户出现异常，待检查订单信息为：{}, 参数为：{}, 响应结果为:{}, 详情为：{}",
                    phoneOrderWaitCheck, params.toString(), result, e);
        }
    }

    /**
     * 发送Http请求
     *
     * @param url    请求路径
     * @param params 参数
     * @return 响应结果
     */
    private String sendRequestForWaitOrder(String url, Map<String, Object> params) {
        return HttpUtils.doPost(url, params, HEADER_MAP);
    }

    /**
     * 放入成功队列
     */
    private void saveWaitOrderQueryForSuccess(PhoneOrderWaitCheck phoneOrderWaitCheck) {
        redisService.lPush(RedisConstant.PUSH_ORDER_WAIT_CHECK_SUCCESS, JSON.toJSONString(phoneOrderWaitCheck));
    }

    /**
     * 放入失败队列 (废弃)
     */
    @Deprecated
    private void saveWaitOrderQueryForFailed(PhoneOrderWaitCheck phoneOrderWaitCheck) {
        redisService.lPush(RedisConstant.PUSH_ORDER_WAIT_CHECK_FAILED, JSON.toJSONString(phoneOrderWaitCheck));
    }

    /**
     * 放入处理中队列
     */
    private void saveWaitOrderQueryForProcessing(PhoneOrderWaitCheck phoneOrderWaitCheck) {
        if (!RechargeTypeEnum.SLOW.getCode().equals(phoneOrderWaitCheck.getRechargeType())) {
            redisService.lPush(RedisConstant.PUSH_ORDER_WAIT_CHECK_PROCESSING, JSON.toJSONString(phoneOrderWaitCheck));
        }
    }
}
